home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume2 / nethack / part09 < prev    next >
Encoding:
Internet Message Format  |  1987-07-29  |  54.9 KB

  1. Path: uunet!seismo!rochester!cornell!uw-beaver!tektronix!tekgen!tekred!games-request
  2. From: games-request@tekred.TEK.COM
  3. Newsgroups: comp.sources.games
  4. Subject: v02i009:  nethack - display oriented dungeons & dragons, Part09/16
  5. Message-ID: <1451@tekred.TEK.COM>
  6. Date: 28 Jul 87 18:49:38 GMT
  7. Sender: billr@tekred.TEK.COM
  8. Lines: 2417
  9. Approved: billr@tekred.TEK.COM
  10.  
  11. Submitted by: mike@genat.UUCP (Mike Stephenson)
  12. Comp.sources.games: Volume 2, Issue 9
  13. Archive-name: nethack/Part09
  14.  
  15.  
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 9 (of 16)."
  24. # Contents:  engrave.c makedefs.c pri.c rumors.c unixmain.c
  25. # Wrapped by billr@tekred on Tue Jul 28 09:49:36 1987
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f engrave.c -a "${1}" != "-c" ; then 
  28.   echo shar: Will not over-write existing file \"engrave.c\"
  29. else
  30. echo shar: Extracting \"engrave.c\" \(12451 characters\)
  31. sed "s/^X//" >engrave.c <<'END_OF_engrave.c'
  32. X/*    SCCS Id: @(#)engrave.c    1.3    87/07/14
  33. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  34. X/* engrave.c - version 1.0.2 */
  35. X
  36. X#include    "hack.h"
  37. X
  38. Xextern char *nomovemsg;
  39. Xextern char nul[];
  40. Xextern struct obj zeroobj;
  41. X#ifdef KAA
  42. Xextern char *xname();
  43. X#endif
  44. Xstruct engr {
  45. X    struct engr *nxt_engr;
  46. X    char *engr_txt;
  47. X    xchar engr_x, engr_y;
  48. X    unsigned engr_lth;    /* for save & restore; not length of text */
  49. X    long engr_time;    /* moment engraving was (will be) finished */
  50. X    xchar engr_type;
  51. X#define    DUST    1
  52. X#define    ENGRAVE    2
  53. X#define    BURN    3
  54. X#ifdef MARKER
  55. X#define MARK    4
  56. X#define POLY    5    /* temporary type - for polymorphing engraving */
  57. X#else
  58. X#define POLY    4    /* temporary type - for polymorphing engraving */
  59. X#endif
  60. X} *head_engr;
  61. X
  62. X/* random engravings */
  63. X#ifdef KAA
  64. Xchar *random_engr[] =
  65. X#else
  66. Xchar random_engr[][30] =
  67. X#endif
  68. X             {"Elbereth", "ad ae?ar um",
  69. X#ifdef NEWCLASS
  70. X             "?la? ?as he??",
  71. X#endif
  72. X            /* more added by Eric Backus */
  73. X            "?ilroy wa? h?re", "?ala??iel", "Aba?don H?pe...",
  74. X            "Fo? a ?ood time c?ll 6?6-4311"};
  75. X#ifdef NEWCLASS
  76. X#define RAND_ENGRS    7
  77. X#else
  78. X#define RAND_ENGRS    6
  79. X#endif
  80. X
  81. Xstruct engr *
  82. Xengr_at(x,y) register xchar x,y; {
  83. Xregister struct engr *ep = head_engr;
  84. X    while(ep) {
  85. X        if(x == ep->engr_x && y == ep->engr_y)
  86. X            return(ep);
  87. X        ep = ep->nxt_engr;
  88. X    }
  89. X    return((struct engr *) 0);
  90. X}
  91. X
  92. Xsengr_at(s,x,y) register char *s; register xchar x,y; {
  93. Xregister struct engr *ep = engr_at(x,y);
  94. Xregister char *t;
  95. Xregister int n;
  96. X    if(ep && ep->engr_time <= moves) {
  97. X        t = ep->engr_txt;
  98. X/*
  99. X        if(!strcmp(s,t)) return(1);
  100. X*/
  101. X        n = strlen(s);
  102. X        while(*t) {
  103. X            if(!strncmp(s,t,n)) return(1);
  104. X            t++;
  105. X        }
  106. X    }
  107. X    return(0);
  108. X}
  109. X
  110. Xu_wipe_engr(cnt)
  111. Xregister int cnt;
  112. X{
  113. X    if(!u.uswallow && !Levitation)
  114. X        wipe_engr_at(u.ux, u.uy, cnt);
  115. X}
  116. X
  117. Xwipe_engr_at(x,y,cnt) register xchar x,y,cnt; {
  118. Xregister struct engr *ep = engr_at(x,y);
  119. Xregister int lth,pos;
  120. Xchar ch;
  121. X    if(ep){
  122. X        if(ep->engr_type != DUST) {
  123. X            cnt = rn2(1 + 50/(cnt+1)) ? 0 : 1;
  124. X        }
  125. X        lth = strlen(ep->engr_txt);
  126. X        if(lth && cnt > 0 ) {
  127. X            while(cnt--) {
  128. X                pos = rn2(lth);
  129. X                if((ch = ep->engr_txt[pos]) == ' ')
  130. X                    continue;
  131. X                ep->engr_txt[pos] = (ch != '?') ? '?' : ' ';
  132. X            }
  133. X        }
  134. X        while(lth && ep->engr_txt[lth-1] == ' ')
  135. X            ep->engr_txt[--lth] = 0;
  136. X        while(ep->engr_txt[0] == ' ')
  137. X            ep->engr_txt++;
  138. X        if(!ep->engr_txt[0]) del_engr(ep);
  139. X    }
  140. X}
  141. X
  142. Xread_engr_at(x,y) register int x,y; {
  143. Xregister struct engr *ep = engr_at(x,y);
  144. X    if(ep && ep->engr_txt[0]) {
  145. X        switch(ep->engr_type) {
  146. X        case DUST:
  147. X        pline("Something is written here in the dust.");
  148. X        break;
  149. X        case ENGRAVE:
  150. X        pline("Something is engraved here on the floor.");
  151. X        break;
  152. X        case BURN:
  153. X        pline("Some text has been burned here in the floor.");
  154. X#ifdef MARKER
  155. X        case MARK:
  156. X        pline("There's some graffiti here on the floor.");
  157. X        break;
  158. X#endif
  159. X        break;
  160. X        default:
  161. X        impossible("Something is written in a very strange way.");
  162. X        }
  163. X        pline("You read: \"%s\".", ep->engr_txt);
  164. X    }
  165. X}
  166. X
  167. Xmake_engr_at(x,y,s)
  168. Xregister int x,y;
  169. Xregister char *s;
  170. X{
  171. X    register struct engr *ep;
  172. X
  173. X    if(ep = engr_at(x,y))
  174. X        del_engr(ep);
  175. X    ep = (struct engr *)
  176. X        alloc((unsigned)(sizeof(struct engr) + strlen(s) + 1));
  177. X    ep->nxt_engr = head_engr;
  178. X    head_engr = ep;
  179. X    ep->engr_x = x;
  180. X    ep->engr_y = y;
  181. X    ep->engr_txt = (char *)(ep + 1);
  182. X    (void) strcpy(ep->engr_txt, s);
  183. X    ep->engr_time = 0;
  184. X    ep->engr_type = DUST;
  185. X    ep->engr_lth = strlen(s) + 1;
  186. X}
  187. X/*
  188. X *    freehand - returns true if player has a free hand
  189. X */
  190. Xint
  191. Xfreehand(){
  192. X
  193. X    return(!uwep ||
  194. X       !uwep->cursed ||
  195. X       (uwep->otyp != TWO_HANDED_SWORD && (!uarms || !uarms->cursed)));
  196. X/*    if ((uwep && uwep->otyp == TWO_HANDED_SWORD) ||
  197. X        (uwep && uarms))
  198. X        return(0);
  199. X    else
  200. X        return(1);*/
  201. X}
  202. X
  203. X
  204. X
  205. Xdoengrave(){
  206. Xregister int len;
  207. Xregister char *sp;
  208. Xregister struct engr *ep, *oep = engr_at(u.ux,u.uy);
  209. Xchar buf[BUFSZ];
  210. Xxchar type;
  211. Xint spct;        /* number of leading spaces */
  212. Xregister struct obj *otmp;
  213. X    multi = 0;
  214. X
  215. X    if(u.uswallow) {
  216. X        pline("You're joking. Hahaha!");    /* riv05!a3 */
  217. X        return(0);
  218. X    }
  219. X
  220. X    /* one may write with finger, weapon or wand */
  221. X    /* edited by GAN 10/20/86 so as not to change
  222. X     * weapon wielded.
  223. X     */
  224. X    otmp = getobj("#-()/", "write with");
  225. X    if(!otmp) return(0);
  226. X
  227. X#ifdef FREEHAND /* There's no reason you should be able to write with a wand
  228. X         * while both your hands are tied up.  Also, it's necessary to
  229. X         * prevent engraving with "worn" objects other than weapons.
  230. X         */
  231. X    if (!freehand() && otmp != uwep) {
  232. X#else
  233. X    /* added by GAN 10/20/86 to require you to need a hand to
  234. X       write with.
  235. X     */
  236. X    if(!(otmp->owornmask || otmp->olet == WAND_SYM) && !freehand())  {
  237. X#endif
  238. X        pline("You have no free hand to write with!");
  239. X        return(0);
  240. X    }
  241. X#ifdef KAA
  242. X    if (cantwield(u.usym)) {
  243. X        pline("You can't even hold anything!");
  244. X        return(0);
  245. X    }
  246. X    if(otmp != &zeroobj && index("][0`",otmp->olet)) {
  247. X        pline("You can't engrave with such a large object!");
  248. X        return(1);
  249. X    }
  250. X#endif
  251. X
  252. X    if(Levitation && otmp->olet != WAND_SYM){        /* riv05!a3 */
  253. X        pline("You can't reach the floor!");
  254. X        return(0);
  255. X    }
  256. X
  257. X    if(otmp == &zeroobj) {
  258. X        pline("You write in the dust with your fingers.");
  259. X        type = DUST;
  260. X    } else if(otmp->olet == WAND_SYM && zappable(otmp)) {
  261. X        /* changed so any wand gets zapped out, but fire
  262. X         * wands become known.
  263. X         */
  264. X        if((objects[otmp->otyp].bits & NODIR))  {
  265. X            zapnodir(otmp);
  266. X            type = DUST;
  267. X        }  else  {
  268. X            switch(otmp->otyp)  {
  269. X            case WAN_FIRE:
  270. X                if(!objects[otmp->otyp].oc_name_known) {
  271. X                    pline("The %s is a wand of fire!",
  272. X                       xname(otmp));
  273. X                    objects[otmp->otyp].oc_name_known = 1;
  274. X                    more_experienced(0,10);
  275. X                }
  276. X                type = BURN;
  277. X                break;
  278. X            case WAN_DIGGING:
  279. X                if(!objects[otmp->otyp].oc_name_known) {
  280. X                    pline("The %s is a wand of digging!",
  281. X                       xname(otmp));
  282. X                    objects[otmp->otyp].oc_name_known = 1;
  283. X                    more_experienced(0,10);
  284. X                }
  285. X                type = ENGRAVE;
  286. X                break;
  287. X            case WAN_POLYMORPH:
  288. X                if(oep)  {
  289. X                    del_engr(oep);
  290. X                    oep = 0;
  291. X                    type = POLY;
  292. X                }  else
  293. X                    type = DUST;
  294. X                break;
  295. X            case WAN_COLD:
  296. X                type = DUST;
  297. X                if(!oep || (oep->engr_type != BURN))
  298. X                    break;
  299. X            case WAN_CANCELLATION:
  300. X            case WAN_MAKE_INVISIBLE:
  301. X                if(!oep) {        /* Eric Backus */
  302. X                    type = DUST;
  303. X                    break;
  304. X                }
  305. X                del_engr(oep);
  306. X                pline("The engraving on the floor vanishes!");
  307. X                return(1);
  308. X                break;
  309. X            case WAN_TELEPORTATION:
  310. X                if(!oep)
  311. X                    type = DUST;
  312. X                else  {
  313. X                    register tx,ty;
  314. X
  315. X                    do  {
  316. X                        tx = rn1(COLNO-3,2);
  317. X                        ty = rn2(ROWNO);
  318. X                    }  while(!goodpos(tx,ty));
  319. X                    oep->engr_x = tx;
  320. X                    oep->engr_y = ty;
  321. X                    pline("The engraving on the floor vanishes!");
  322. X                    return(1);
  323. X                }
  324. X                break;
  325. X            default:
  326. X                type = DUST;
  327. X            }
  328. X        }
  329. X        if(type == DUST)
  330. X            pline("You write in the dust with %s.",
  331. X               doname(otmp));
  332. X    
  333. X    } else {
  334. X        if(otmp->otyp == DAGGER || otmp->otyp == TWO_HANDED_SWORD ||
  335. X        otmp->otyp == CRYSKNIFE || otmp->otyp == KATANA ||
  336. X        otmp->otyp == SCIMITAR || otmp->otyp == BROAD_SWORD ||
  337. X        otmp->otyp == SHORT_SWORD ||
  338. X        otmp->otyp == LONG_SWORD || otmp->otyp == AXE) {
  339. X            type = ENGRAVE;
  340. X            if((int)otmp->spe <= -3) {
  341. X                pline("Your %s too dull for engraving.",
  342. X                    aobjnam(otmp, "are"));
  343. X                type = DUST;
  344. X                /* following messaged added 10/20/86 - GAN */
  345. X                pline("You write in the dust with %s.",
  346. X                   doname(otmp));
  347. X            }  else
  348. X                pline("You engrave with %s.", doname(otmp));
  349. X#ifdef MARKER
  350. X        } else if(otmp->otyp == MAGIC_MARKER)  {
  351. X            if(otmp->spe <= 0)  {
  352. X                pline("Your marker is dried out.");
  353. X                pline("You write in the dust with the marker.");
  354. X                type = DUST;
  355. X            }  else  {
  356. X                pline("You write with %s.", doname(otmp));
  357. X                type = MARK;
  358. X            }
  359. X#endif
  360. X        }  else  {
  361. X            pline("You write in the dust with %s.",
  362. X               doname(otmp));
  363. X            type = DUST;
  364. X        }
  365. X    }
  366. X    
  367. X    if(type != POLY && oep && oep->engr_type == DUST){
  368. X          pline("You wipe out the message that was written here.");
  369. X          del_engr(oep);
  370. X          oep = 0;
  371. X    }
  372. X    if(type == DUST && oep){
  373. X    pline("You cannot wipe out the message that is %s in the rock.",
  374. X            (oep->engr_type == BURN) ? "burned" : (oep->engr_type == ENGRAVE)? "engraved" : "scribbled");
  375. X          return(1);
  376. X    }
  377. X    if(type == POLY)  {
  378. X#ifdef MARKER
  379. X        type = rnd(4);
  380. X#else
  381. X        type = rnd(3);
  382. X#endif
  383. X        strcpy(buf,random_engr[rn2(RAND_ENGRS)]);
  384. X        switch(type){
  385. X        case DUST:
  386. X            pline("\"%s\" is now written on the ground.",buf);
  387. X            break;
  388. X        case ENGRAVE:
  389. X            pline("\"%s\" is now engraved in the rock.",buf);
  390. X            break;
  391. X        case BURN:
  392. X            pline("\"%s\" is now burned in the rock.",buf);
  393. X            break;
  394. X#ifdef MARKER
  395. X        case MARK:
  396. X            pline("\"%s\" is now scribbled on the rock.",buf);
  397. X            break;
  398. X#endif
  399. X        default:
  400. X            impossible("\"%s\" is now written in a very strange way.",
  401. X               buf);
  402. X        }
  403. X    }  else  {
  404. X        pline("What do you want to %s on the floor here? ",
  405. X          (type == ENGRAVE) ? "engrave" : (type == BURN) ? "burn" : "write");
  406. X        getlin(buf);
  407. X        clrlin();
  408. X    }
  409. X    spct = 0;
  410. X    sp = buf;
  411. X    while(*sp == ' ') spct++, sp++;
  412. X    len = strlen(sp);
  413. X    if(!len || *buf == '\033') {
  414. X        /* changed by GAN 11/01/86 to not recharge wand */
  415. X        if(type == BURN)
  416. X            pline("A few sparks fly from the wand of fire.");
  417. X        else
  418. X            if(otmp->otyp == WAN_DIGGING)
  419. X                pline("Gravel flies up from the floor.");
  420. X        return(1);
  421. X    }
  422. X    
  423. X    switch(type) {
  424. X    case DUST:
  425. X    case BURN:
  426. X        if(len > 15) {
  427. X            multi = -(len/10);
  428. X            nomovemsg = "You finished writing.";
  429. X        }
  430. X        break;
  431. X    case ENGRAVE:
  432. X#ifdef MARKER
  433. X    case MARK:
  434. X        {    int len2;
  435. X        
  436. X            if(type == ENGRAVE)
  437. X                len2 = (otmp->spe + 3) * 2 + 1;
  438. X            else
  439. X                len2 = (otmp->spe) * 2;
  440. X            nomovemsg = "You finished writing.";
  441. X            if(type != MARK)
  442. X#else
  443. X        {    int len2 = (otmp->spe + 3) * 2 + 1;
  444. X#endif
  445. X            nomovemsg = "You finished engraving.";
  446. X            if(otmp->olet != WAND_SYM)  {
  447. X                if(otmp->olet == WEAPON_SYM)
  448. X                    pline("Your %s dull.",
  449. X                           aobjnam(otmp, "get"));
  450. X                if(len2 < len) {
  451. X                    len = len2;
  452. X                    sp[len] = 0;
  453. X                    if(type == ENGRAVE)  {
  454. X                        otmp->spe = -3;
  455. X                    }  else  {
  456. X                        pline("Your marker dries out!");
  457. X                        otmp->spe = 0;
  458. X                    }
  459. X                    /* next line added by GAN 10/20/86 */
  460. X                    pline("You only write \"%s\".", sp);
  461. X                    nomovemsg = "You cannot write more.";
  462. X                } else
  463. X                    otmp->spe -= len/2;
  464. X#ifdef MARKER
  465. X                if(type == MARK)
  466. X                    multi = -(len/10);
  467. X                else
  468. X#endif
  469. X                    multi = -len;
  470. X            }  else
  471. X                multi = -(len/10);
  472. X        }
  473. X        break;
  474. X    }
  475. X    if(oep) len += strlen(oep->engr_txt) + spct;
  476. X    ep = (struct engr *) alloc((unsigned)(sizeof(struct engr) + len + 1));
  477. X    ep->nxt_engr = head_engr;
  478. X    head_engr = ep;
  479. X    ep->engr_x = u.ux;
  480. X    ep->engr_y = u.uy;
  481. X    sp = (char *)(ep + 1);    /* (char *)ep + sizeof(struct engr) */
  482. X    ep->engr_txt = sp;
  483. X    if(oep) {
  484. X        (void) strcpy(sp, oep->engr_txt);
  485. X        (void) strcat(sp, buf);
  486. X        del_engr(oep);
  487. X    } else
  488. X        (void) strcpy(sp, buf);
  489. X    ep->engr_lth = len+1;
  490. X    ep->engr_type = type;
  491. X    ep->engr_time = moves-multi;
  492. X
  493. X    /* kludge to protect pline against excessively long texts */
  494. X    if(len > BUFSZ-20) sp[BUFSZ-20] = 0;
  495. X    
  496. X    /* cute messages for odd wands */
  497. X    switch(otmp->otyp)  {
  498. X    case WAN_SLOW_MONSTER:
  499. X        pline("The bugs on the ground slow down!");
  500. X        break;
  501. X    case WAN_SPEED_MONSTER:
  502. X        pline("The bugs on the ground speed up!");
  503. X        break;
  504. X    case WAN_MAGIC_MISSILE:
  505. X        pline("The ground is riddled by bullet holes!");
  506. X        break;
  507. X    case WAN_SLEEP:
  508. X    case WAN_DEATH:    /* can't tell sleep from death - Eric Backus */
  509. X        pline("The bugs on the ground stop moving!");
  510. X        break;
  511. X    case WAN_COLD:
  512. X        pline("A few ice cubes drop from your %s.",xname(otmp));
  513. X        break;
  514. X    case WAN_STRIKING:
  515. X        pline("The %s unsuccessfully fights your attempt to write!",xname(otmp));
  516. X    }
  517. X
  518. X    return(1);
  519. X}
  520. X
  521. Xsave_engravings(fd) int fd; {
  522. Xregister struct engr *ep = head_engr;
  523. X    while(ep) {
  524. X        if(!ep->engr_lth || !ep->engr_txt[0]){
  525. X            ep = ep->nxt_engr;
  526. X            continue;
  527. X        }
  528. X        bwrite(fd, (char *) & (ep->engr_lth), sizeof(ep->engr_lth));
  529. X        bwrite(fd, (char *) ep, sizeof(struct engr) + ep->engr_lth);
  530. X        ep = ep->nxt_engr;
  531. X    }
  532. X    bwrite(fd, (char *) nul, sizeof(unsigned));
  533. X#ifdef DGK
  534. X    if (!count_only)
  535. X#endif
  536. X        head_engr = 0;
  537. X}
  538. X
  539. Xrest_engravings(fd) int fd; {
  540. Xregister struct engr *ep;
  541. Xunsigned lth;
  542. X    head_engr = 0;
  543. X    while(1) {
  544. X        mread(fd, (char *) <h, sizeof(unsigned));
  545. X        if(lth == 0) return;
  546. X        ep = (struct engr *) alloc(sizeof(struct engr) + lth);
  547. X        mread(fd, (char *) ep, sizeof(struct engr) + lth);
  548. X        ep->nxt_engr = head_engr;
  549. X        ep->engr_txt = (char *) (ep + 1);    /* Andreas Bormann */
  550. X        head_engr = ep;
  551. X    }
  552. X}
  553. X
  554. Xdel_engr(ep) register struct engr *ep; {
  555. Xregister struct engr *ept;
  556. X    if(ep == head_engr)
  557. X        head_engr = ep->nxt_engr;
  558. X    else {
  559. X        for(ept = head_engr; ept; ept = ept->nxt_engr) {
  560. X            if(ept->nxt_engr == ep) {
  561. X                ept->nxt_engr = ep->nxt_engr;
  562. X                goto fnd;
  563. X            }
  564. X        }
  565. X        impossible("Error in del_engr?");
  566. X        return;
  567. X    fnd:    ;
  568. X    }
  569. X    free((char *) ep);
  570. X}
  571. END_OF_engrave.c
  572. if test 12451 -ne `wc -c <engrave.c`; then
  573.     echo shar: \"engrave.c\" unpacked with wrong size!
  574. fi
  575. # end of overwriting check
  576. fi
  577. if test -f makedefs.c -a "${1}" != "-c" ; then 
  578.   echo shar: Will not over-write existing file \"makedefs.c\"
  579. else
  580. echo shar: Extracting \"makedefs.c\" \(11657 characters\)
  581. sed "s/^X//" >makedefs.c <<'END_OF_makedefs.c'
  582. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  583. X/* makedefs.c - NetHack version 1.0 */
  584. X
  585. Xstatic    char    SCCS_Id[] = "@(#)makedefs.c    1.3\t87/07/14";
  586. X
  587. X#include    "config.h"
  588. X#include    <stdio.h>
  589. X
  590. X#ifdef MSDOS
  591. X#undef    exit
  592. X#endif
  593. X
  594. X/* construct definitions of object constants */
  595. X#define    OBJ_FILE    "objects.h"
  596. X#define    ONAME_FILE    "onames.h"
  597. X#define    TRAP_FILE    "trap.h"
  598. X#define    DATE_FILE    "date.h"
  599. X#define    RUMOR_FILE    "rumors"
  600. X#define    DATA_FILE    "data"
  601. X
  602. Xchar    inline[256], outline[256];
  603. X
  604. Xmain(argc, argv)
  605. X    int    argc;
  606. X    char    *argv[];
  607. X{
  608. X    char    *option;
  609. X
  610. X    if(argc == 2) {
  611. X        option = argv[1];
  612. X        switch (option[1]) {
  613. X
  614. X        case 'o':
  615. X        case 'O':    do_objs();
  616. X                break;
  617. X        case 't':
  618. X        case 'T':    do_traps();
  619. X                break;
  620. X        case 'r':
  621. X        case 'R':    do_rumors();
  622. X                break;
  623. X
  624. X        case 'd':    do_data();
  625. X                break;
  626. X
  627. X        case 'D':    do_date();
  628. X                break;
  629. X        default:
  630. X                fprintf(stderr, "Unknown option '%c'.\n", option[1]);
  631. X                exit(1);
  632. X        }
  633. X        exit(0);
  634. X    } else    fprintf(stderr, "Bad arg count (%d).\n", argc-1);
  635. X    exit(1);
  636. X}
  637. X
  638. Xdo_traps() {
  639. Xint    ntrap, getpid();
  640. Xchar    tmpfile[30];
  641. XFILE    *freopen();
  642. X
  643. X    sprintf(tmpfile, "makedefs.%d", getpid());
  644. X    if(freopen(tmpfile, "w+", stdout) == NULL) {
  645. X
  646. X        perror(tmpfile);
  647. X        exit(1);
  648. X    }
  649. X    if(freopen(TRAP_FILE, "r+", stdin) == NULL) {
  650. X
  651. X        perror(TRAP_FILE);
  652. X        exit(1);
  653. X    }
  654. X
  655. X    while(gets(inline) != NULL) {
  656. X
  657. X        puts(inline);
  658. X        if(!strncmp(inline, "/* DO NOT REMOVE THIS LINE */", 29)) break;
  659. X    }
  660. X    ntrap = 10;
  661. X    printf("\n");
  662. X
  663. X#ifdef NEWTRAPS
  664. X    printf("#define\tMGTRP\t\t%d\n", ntrap++);
  665. X    printf("#define\tSQBRD\t\t%d\n", ntrap++);
  666. X#endif
  667. X#ifdef SPIDERS
  668. X    printf("#define\tWEB\t\t%d\n", ntrap++);
  669. X#endif
  670. X#ifdef NEWCLASS
  671. X    printf("#define\tSPIKED_PIT\t%d\n", ntrap++);
  672. X    printf("#define\tLEVEL_TELEP\t%d\n", ntrap++);
  673. X#endif
  674. X#ifdef SPELLS
  675. X    printf("#define\tANTI_MAGIC\t%d\n", ntrap++);
  676. X#endif
  677. X#ifdef KAA
  678. X    printf("#define\tRUST_TRAP\t%d\n", ntrap++);
  679. X#endif
  680. X    printf("\n#define\tTRAPNUM\t%d\n", ntrap);
  681. X    fclose(stdin);
  682. X    fclose(stdout);
  683. X    rename(tmpfile, TRAP_FILE);
  684. X}
  685. X
  686. X
  687. Xstruct    hline {
  688. X    struct    hline    *next;
  689. X    char    *line;
  690. X}    *f_line;
  691. X
  692. Xdo_rumors(){
  693. Xstruct    hline    *c_line;
  694. Xchar    infile[30];
  695. XFILE    *freopen();
  696. X
  697. X    if(freopen(RUMOR_FILE, "w+", stdout) == NULL) {
  698. X
  699. X        perror(RUMOR_FILE);
  700. X        exit(1);
  701. X    }
  702. X    sprintf(infile, "%s.base", RUMOR_FILE);
  703. X    if(freopen(infile, "r+", stdin) == NULL) {
  704. X
  705. X        perror(infile);
  706. X        exit(1);
  707. X    }
  708. X
  709. X    while(gets(inline) != NULL)    puts(inline);
  710. X
  711. X#ifdef KAA
  712. X    sprintf(infile, "%s.kaa", RUMOR_FILE);
  713. X    if(freopen(infile, "r+", stdin) == NULL)    perror(infile);
  714. X
  715. X    while(gets(inline) != NULL)    puts(inline);
  716. X#endif
  717. X
  718. X#ifdef NEWCLASS
  719. X    sprintf(infile, "%s.mrx", RUMOR_FILE);
  720. X    if(freopen(infile, "r+", stdin) == NULL)    perror(infile);
  721. X
  722. X    while(gets(inline) != NULL)    puts(inline);
  723. X#endif
  724. X    fclose(stdin);
  725. X    fclose(stdout);
  726. X}
  727. X
  728. Xdo_date(){
  729. Xint    getpid();
  730. Xlong    clock, time();
  731. Xchar    tmpfile[30], cbuf[30], *c, *ctime();
  732. XFILE    *freopen();
  733. X
  734. X    sprintf(tmpfile, "makedefs.%d", getpid());
  735. X    if(freopen(tmpfile, "w+", stdout) == NULL) {
  736. X
  737. X        perror(tmpfile);
  738. X        exit(1);
  739. X    }
  740. X    if(freopen(DATE_FILE, "r+", stdin) == NULL) {
  741. X
  742. X        perror(DATE_FILE);
  743. X        exit(1);
  744. X    }
  745. X
  746. X    while(gets(inline) != NULL) {
  747. X
  748. X        if(!strncmp(inline, "char datestring[] = ", 20)) break;
  749. X        puts(inline);
  750. X    }
  751. X    time(&clock);
  752. X    strcpy(cbuf, ctime(&clock));
  753. X    for(c = cbuf; *c != '\n'; c++);    *c = 0; /* strip off the '\n' */
  754. X    printf("char datestring[] = %c%s%c;\n", '"', cbuf, '"');
  755. X
  756. X    fclose(stdin);
  757. X    fclose(stdout);
  758. X    rename(tmpfile, DATE_FILE);
  759. X}
  760. X
  761. Xdo_data(){
  762. Xint    getpid();
  763. Xchar    tmpfile[30];
  764. XFILE    *freopen();
  765. X
  766. X    sprintf(tmpfile, "%s.base", DATA_FILE);
  767. X    if(freopen(tmpfile, "r+", stdin) == NULL) {
  768. X
  769. X        perror(tmpfile);
  770. X        exit(1);
  771. X    }
  772. X    if(freopen(DATA_FILE, "w+", stdout) == NULL) {
  773. X
  774. X        perror(DATA_FILE);
  775. X        exit(1);
  776. X    }
  777. X
  778. X    while(gets(inline) != NULL) {
  779. X#ifdef KOPS
  780. X        if(!strcmp(inline, "K    a kobold"))
  781. X        printf("K\ta Keystone Kop\n");
  782. X        else
  783. X#endif
  784. X#ifdef KAA
  785. X        if(!strcmp(inline, "Q    a quasit"))
  786. X        printf("Q\ta quantum mechanic\n");
  787. X        else
  788. X#endif
  789. X#ifdef ROCKMOLE
  790. X        if(!strcmp(inline, "r    a giant rat"))
  791. X        printf("K\ta rockmole\n");
  792. X        else
  793. X#endif
  794. X#ifdef SPIDERS
  795. X        if(!strcmp(inline, "s    a scorpion"))
  796. X        printf("s\ta giant spider\n");
  797. X        else
  798. X#endif
  799. X        puts(inline);
  800. X    }
  801. X#ifdef KAA
  802. X    printf("9\ta giant\n");
  803. X#endif
  804. X
  805. X    fclose(stdin);
  806. X    fclose(stdout);
  807. X}
  808. X
  809. X#define    LINSZ    1000
  810. X#define    STRSZ    40
  811. X
  812. Xint    fd;
  813. Xstruct    objdef {
  814. X
  815. X    struct    objdef    *next;
  816. X    char    string[STRSZ];
  817. X}    *more, *current;
  818. X
  819. Xdo_objs(){
  820. Xregister int index = 0;
  821. Xregister int propct = 0;
  822. X#ifdef SPELLS
  823. Xregister int nspell = 0;
  824. X#endif
  825. XFILE    *freopen();
  826. Xregister char *sp;
  827. Xchar    *limit();
  828. Xint skip;
  829. X
  830. X    fd = open(OBJ_FILE, 0);
  831. X    if(fd < 0) {
  832. X        perror(OBJ_FILE);
  833. X        exit(1);
  834. X    }
  835. X
  836. X    if(freopen(ONAME_FILE, "w+", stdout) == NULL) {
  837. X        perror(ONAME_FILE);
  838. X        exit(1);
  839. X    }
  840. X
  841. X    current = 0; newobj();
  842. X    skipuntil("objects[] = {");
  843. X
  844. X    while(getentry(&skip)) {
  845. X        if(!*(current->string)){
  846. X            if (skip) index++;
  847. X            continue;
  848. X        }
  849. X        for(sp = current->string; *sp; sp++)
  850. X            if(*sp == ' ' || *sp == '\t' || *sp == '-')
  851. X                *sp = '_';
  852. X
  853. X        /* Do not process duplicates caused by #ifdef/#else pairs. */
  854. X        /* M. Stephenson                       */
  855. X        if (! duplicate()) {
  856. X
  857. X            if(!strncmp(current->string, "RIN_", 4))
  858. X                specprop(current->string+4, propct++);
  859. X            for(sp = current->string; *sp; sp++) capitalize(sp);
  860. X            /* avoid trouble with stupid C preprocessors */
  861. X            if(!strncmp(current->string, "WORTHLESS_PIECE_OF_", 19))
  862. X            printf("/* #define\t%s\t%d */\n", current->string, index++);
  863. X            else  {
  864. X#ifdef SPELLS
  865. X            if(!strncmp(current->string, "SPE_", 4))  nspell++;
  866. X            printf("#define\t%s\t%d\n", limit(current->string), index++);
  867. X#else
  868. X            if(strncmp(current->string, "SPE_", 4))
  869. X                printf("#define\t%s\t%d\n", limit(current->string), index++);
  870. X#endif
  871. X            }
  872. X            newobj();
  873. X        }
  874. X    }
  875. X    printf("\n#define    CORPSE        DEAD_HUMAN\n");
  876. X#ifdef KOPS
  877. X    printf("#define    DEAD_KOP        DEAD_KOBOLD\n");
  878. X#endif
  879. X#ifdef SPIDERS
  880. X    printf("#define    DEAD_GIANT_SPIDER    DEAD_GIANT_SCORPION\n");
  881. X#endif
  882. X#ifdef ROCKMOLE
  883. X    printf("#define    DEAD_ROCKMOLE        DEAD_GIANT_RAT\n");
  884. X#endif
  885. X#ifndef KAA
  886. X    printf("#define DEAD_QUASIT        DEAD_QUANTUM_MECHANIC\n");
  887. X    printf("#define DEAD_VIOLET_FUNGI    DEAD_VIOLET_FUNGUS\n");
  888. X#endif
  889. X    printf("#define    LAST_GEM    (JADE+1)\n");
  890. X    printf("#define    LAST_RING    %d\n", propct);
  891. X#ifdef SPELLS
  892. X    printf("#define MAXSPELL    %d\n", nspell+1);
  893. X#endif
  894. X    printf("#define    NROFOBJECTS    %d\n", index-1);
  895. X    exit(0);
  896. X}
  897. X
  898. Xstatic    char    temp[32];
  899. X
  900. Xchar *
  901. Xlimit(name)    /* limit a name to 30 characters length */
  902. X    char    *name;
  903. X{
  904. X    strncpy(temp, name, 30);
  905. X    temp[30] = 0;
  906. X    return(temp);
  907. X}
  908. X
  909. Xnewobj()
  910. X{
  911. X    extern    long    *alloc();
  912. X
  913. X    more = current;
  914. X    current = (struct objdef *)alloc(sizeof(struct objdef));
  915. X    current->next = more;
  916. X}
  917. X
  918. Xstruct inherent {
  919. X
  920. X    char    *attrib,
  921. X        *monsters;
  922. X}    abilities[] = { "Regeneration", "TVi",
  923. X            "See_invisible", "I",
  924. X            "Poison_resistance", "abcghikqsuvxyADFQSVWXZ&",
  925. X            "Fire_resistance", "gD&",
  926. X            "Cold_resistance", "gFY",
  927. X            "Teleportation", "LNt",
  928. X            "Teleport_control", "t",
  929. X            "", "" };
  930. X
  931. Xspecprop(name, count)
  932. X
  933. X    char    *name;
  934. X    int    count;
  935. X{
  936. X    int    i;
  937. X    char    *tname, *limit();
  938. X
  939. X    tname = limit(name);
  940. X    capitalize(tname);
  941. X    for(i = 0; strlen(abilities[i].attrib); i++)
  942. X        if(!strcmp(abilities[i].attrib, tname)) {
  943. X
  944. X        printf("#define\tH%s\tu.uprops[%d].p_flgs\n", tname, count);
  945. X        printf("#define\t%s\t((H%s) || index(\"%s\", u.usym))\n",
  946. X            tname, tname, abilities[i].monsters);
  947. X        return(0);
  948. X        }
  949. X
  950. X    printf("#define\t%s\tu.uprops[%d].p_flgs\n", tname, count);
  951. X    return(0);
  952. X}
  953. X
  954. Xchar line[LINSZ], *lp = line, *lp0 = line, *lpe = line;
  955. Xint xeof;
  956. X
  957. Xreadline(){
  958. Xregister int n = read(fd, lp0, (line+LINSZ)-lp0);
  959. X    if(n < 0){
  960. X        printf("Input error.\n");
  961. X        exit(1);
  962. X    }
  963. X    if(n == 0) xeof++;
  964. X    lpe = lp0+n;
  965. X}
  966. X
  967. Xchar
  968. Xnextchar(){
  969. X    if(lp == lpe){
  970. X        readline();
  971. X        lp = lp0;
  972. X    }
  973. X    return((lp == lpe) ? 0 : *lp++);
  974. X}
  975. X
  976. Xskipuntil(s) char *s; {
  977. Xregister char *sp0, *sp1;
  978. Xloop:
  979. X    while(*s != nextchar())
  980. X        if(xeof) {
  981. X            printf("Cannot skipuntil %s\n", s);
  982. X            exit(1);
  983. X        }
  984. X    if(strlen(s) > lpe-lp+1){
  985. X        register char *lp1, *lp2;
  986. X        lp2 = lp;
  987. X        lp1 = lp = lp0;
  988. X        while(lp2 != lpe) *lp1++ = *lp2++;
  989. X        lp2 = lp0;    /* save value */
  990. X        lp0 = lp1;
  991. X        readline();
  992. X        lp0 = lp2;
  993. X        if(strlen(s) > lpe-lp+1) {
  994. X            printf("error in skipuntil");
  995. X            exit(1);
  996. X        }
  997. X    }
  998. X    sp0 = s+1;
  999. X    sp1 = lp;
  1000. X    while(*sp0 && *sp0 == *sp1) sp0++, sp1++;
  1001. X    if(!*sp0){
  1002. X        lp = sp1;
  1003. X        return(1);
  1004. X    }
  1005. X    goto loop;
  1006. X}
  1007. X
  1008. Xgetentry(skip) int *skip; {
  1009. Xint inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0;
  1010. Xint prefix = 0;
  1011. Xchar ch;
  1012. X#define    NSZ    10
  1013. Xchar identif[NSZ], *ip;
  1014. X    current->string[0] = current->string[4] = 0;
  1015. X    /* read until {...} or XXX(...) followed by ,
  1016. X       skip comment and #define lines
  1017. X       deliver 0 on failure
  1018. X     */
  1019. X    while(1) {
  1020. X        ch = nextchar();
  1021. X    swi:
  1022. X        if(letter(ch)){
  1023. X            ip = identif;
  1024. X            do {
  1025. X                if(ip < identif+NSZ-1) *ip++ = ch;
  1026. X                ch = nextchar();
  1027. X            } while(letter(ch) || digit(ch));
  1028. X            *ip = 0;
  1029. X            while(ch == ' ' || ch == '\t') ch = nextchar();
  1030. X            if(ch == '(' && !inparens && !stringseen)
  1031. X                if(!strcmp(identif, "WAND") ||
  1032. X                   !strcmp(identif, "RING") ||
  1033. X                   !strcmp(identif, "POTION") ||
  1034. X                   !strcmp(identif, "SPELL") ||
  1035. X                   !strcmp(identif, "SCROLL"))
  1036. X                (void) strncpy(current->string, identif, 3),
  1037. X                current->string[3] = '_',
  1038. X                prefix = 4;
  1039. X        }
  1040. X        switch(ch) {
  1041. X        case '/':
  1042. X            /* watch for comment */
  1043. X            if((ch = nextchar()) == '*')
  1044. X                skipuntil("*/");
  1045. X            goto swi;
  1046. X        case '{':
  1047. X            inbraces++;
  1048. X            continue;
  1049. X        case '(':
  1050. X            inparens++;
  1051. X            continue;
  1052. X        case '}':
  1053. X            inbraces--;
  1054. X            if(inbraces < 0) return(0);
  1055. X            continue;
  1056. X        case ')':
  1057. X            inparens--;
  1058. X            if(inparens < 0) {
  1059. X                printf("too many ) ?");
  1060. X                exit(1);
  1061. X            }
  1062. X            continue;
  1063. X        case '\n':
  1064. X            /* watch for #define at begin of line */
  1065. X            if((ch = nextchar()) == '#'){
  1066. X                register char pch;
  1067. X                /* skip until '\n' not preceded by '\\' */
  1068. X                do {
  1069. X                    pch = ch;
  1070. X                    ch = nextchar();
  1071. X                } while(ch != '\n' || pch == '\\');
  1072. X                continue;
  1073. X            }
  1074. X            goto swi;
  1075. X        case ',':
  1076. X            if(!inparens && !inbraces){
  1077. X                if(prefix && !current->string[prefix]) {
  1078. X#ifndef SPELLS
  1079. X                    *skip = strncmp(current->string, "SPE_", 4);
  1080. X#else
  1081. X                    *skip = 1;
  1082. X#endif
  1083. X                    current->string[0] = 0;
  1084. X                }
  1085. X                if(stringseen) return(1);
  1086. X                printf("unexpected ,\n");
  1087. X                exit(1);
  1088. X            }
  1089. X            commaseen++;
  1090. X            continue;
  1091. X        case '\'':
  1092. X            if((ch = nextchar()) == '\\') ch = nextchar();
  1093. X            if(nextchar() != '\''){
  1094. X                printf("strange character denotation?\n");
  1095. X                exit(1);
  1096. X            }
  1097. X            continue;
  1098. X        case '"':
  1099. X            {
  1100. X                register char *sp = current->string + prefix;
  1101. X                register char pch;
  1102. X                register int store = (inbraces || inparens)
  1103. X                    && !stringseen++ && !commaseen;
  1104. X                do {
  1105. X                    pch = ch;
  1106. X                    ch = nextchar();
  1107. X                    if(store && sp < current->string+STRSZ)
  1108. X                        *sp++ = ch;
  1109. X                } while(ch != '"' || pch == '\\');
  1110. X                if(store) *--sp = 0;
  1111. X                continue;
  1112. X            }
  1113. X        }
  1114. X    }
  1115. X}
  1116. X
  1117. Xduplicate() {
  1118. X
  1119. X    char    s[STRSZ];
  1120. X    register char    *c;
  1121. X    register struct    objdef    *testobj;
  1122. X
  1123. X    strcpy (s, current->string);
  1124. X    for(c = s; *c != 0; c++) capitalize(c);
  1125. X
  1126. X    for(testobj = more; testobj != 0; testobj = testobj->next)
  1127. X        if(! strcmp(s, testobj->string)) return(1);
  1128. X
  1129. X    return(0);
  1130. X}
  1131. X
  1132. Xcapitalize(sp) register char *sp; {
  1133. X    if('a' <= *sp && *sp <= 'z') *sp += 'A'-'a';
  1134. X}
  1135. X
  1136. Xletter(ch) register char ch; {
  1137. X    return( ('a' <= ch && ch <= 'z') ||
  1138. X        ('A' <= ch && ch <= 'Z') );
  1139. X}
  1140. X
  1141. Xdigit(ch) register char ch; {
  1142. X    return( '0' <= ch && ch <= '9' );
  1143. X}
  1144. X
  1145. X/* a copy of the panic code from hack.pri.c, edited for standalone use */
  1146. X
  1147. Xboolean    panicking = 0;
  1148. X
  1149. Xpanic(str,a1,a2,a3,a4,a5,a6)
  1150. Xchar *str;
  1151. X{
  1152. X    if(panicking++) exit(1);    /* avoid loops - this should never happen*/
  1153. X    fputs(" ERROR:  ", stdout);
  1154. X    printf(str,a1,a2,a3,a4,a5,a6);
  1155. X#ifdef DEBUG
  1156. X# ifdef UNIX
  1157. X    if(!fork())
  1158. X        abort();    /* generate core dump */
  1159. X# endif
  1160. X#endif
  1161. X    exit(1);
  1162. X}
  1163. X
  1164. X#ifdef SYSV
  1165. Xrename(oldname, newname)
  1166. X    char    *oldname, *newname;
  1167. X{
  1168. X    if (strcmp(oldname, newname)) {
  1169. X
  1170. X        unlink(newname);
  1171. X        link(oldname, newname);
  1172. X        unlink(oldname);
  1173. X    }
  1174. X}
  1175. X#endif
  1176. END_OF_makedefs.c
  1177. if test 11657 -ne `wc -c <makedefs.c`; then
  1178.     echo shar: \"makedefs.c\" unpacked with wrong size!
  1179. fi
  1180. # end of overwriting check
  1181. fi
  1182. if test -f pri.c -a "${1}" != "-c" ; then 
  1183.   echo shar: Will not over-write existing file \"pri.c\"
  1184. else
  1185. echo shar: Extracting \"pri.c\" \(11689 characters\)
  1186. sed "s/^X//" >pri.c <<'END_OF_pri.c'
  1187. X/*    SCCS Id: @(#)pri.c    1.3    87/07/14
  1188. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1189. X/* pri.c - version 1.0.3 */
  1190. X
  1191. X#include <stdio.h>
  1192. X#include "hack.h"
  1193. X
  1194. X#define DEBUG
  1195. Xxchar scrlx, scrhx, scrly, scrhy;    /* corners of new area on screen */
  1196. X
  1197. Xextern char *hu_stat[];    /* in eat.c */
  1198. Xextern char *CD;
  1199. X
  1200. Xswallowed()
  1201. X{
  1202. X    char *ulook = "|@|";
  1203. X    ulook[1] = u.usym;
  1204. X
  1205. X    cls();
  1206. X    curs(u.ux-1, u.uy+1);
  1207. X    fputs("/-\\", stdout);
  1208. X    curx = u.ux+2;
  1209. X    curs(u.ux-1, u.uy+2);
  1210. X    fputs(ulook, stdout);
  1211. X    curx = u.ux+2;
  1212. X    curs(u.ux-1, u.uy+3);
  1213. X    fputs("\\-/", stdout);
  1214. X    curx = u.ux+2;
  1215. X    u.udispl = 1;
  1216. X    u.udisx = u.ux;
  1217. X    u.udisy = u.uy;
  1218. X}
  1219. X
  1220. Xsetclipped(){
  1221. X    error("Hack needs a screen of size at least %d by %d.\n",
  1222. X        ROWNO+2, COLNO);
  1223. X}
  1224. X
  1225. X#ifdef DGK
  1226. Xstatic int multipleAts;        /* TRUE if we have many at()'s to do */
  1227. Xstatic int DECgraphics;        /* The graphics mode toggle */
  1228. X
  1229. X#define DECgraphicsON() ((void) putchar('\16'), DECgraphics = TRUE)
  1230. X#define DECgraphicsOFF() ((void) putchar('\17'), DECgraphics = FALSE)
  1231. X#endif
  1232. X
  1233. Xat(x,y,ch)
  1234. Xregister xchar x,y;
  1235. Xchar ch;
  1236. X{
  1237. X#ifndef lint
  1238. X    /* if xchar is unsigned, lint will complain about  if(x < 0)  */
  1239. X    if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1) {
  1240. X        impossible("At gets 0%o at %d %d.", ch, x, y);
  1241. X        return;
  1242. X    }
  1243. X#endif
  1244. X    if(!ch) {
  1245. X        impossible("At gets null at %d %d.", x, y);
  1246. X        return;
  1247. X    }
  1248. X    y += 2;
  1249. X    curs(x,y);
  1250. X#ifdef DGK
  1251. X    if (flags.DECRainbow) {
  1252. X        /* If there are going to be many at()s in a row without
  1253. X         * intervention, only change the graphics mode when the
  1254. X         * character changes between graphic and regular.
  1255. X         */
  1256. X        if (multipleAts) {
  1257. X            if (ch & 0x80) {
  1258. X                if (!DECgraphics)
  1259. X                    DECgraphicsON();
  1260. X                (void) putchar(ch ^ 0x80); /* Strip 8th bit */
  1261. X            } else {
  1262. X                if (DECgraphics)
  1263. X                    DECgraphicsOFF();
  1264. X                (void) putchar(ch);
  1265. X            }
  1266. X        /* Otherwise, we don't know how many at()s will be happening
  1267. X         * before printing of normal strings, so change to graphics
  1268. X         * mode when necessary, then change right back.
  1269. X         */
  1270. X        } else {
  1271. X            if (ch & 0x80) {
  1272. X                DECgraphicsON();
  1273. X                (void) putchar(ch ^ 0x80); /* Strip 8th bit */
  1274. X                DECgraphicsOFF();
  1275. X            } else
  1276. X                (void) putchar(ch);
  1277. X        }
  1278. X    } else
  1279. X#endif
  1280. X        (void) putchar(ch);
  1281. X    curx++;
  1282. X}
  1283. X
  1284. Xprme(){
  1285. X    if(!Invisible) at(u.ux,u.uy,u.usym);
  1286. X}
  1287. X
  1288. Xdoredraw()
  1289. X{
  1290. X    docrt();
  1291. X    return(0);
  1292. X}
  1293. X
  1294. Xdocrt()
  1295. X{
  1296. X    register x,y;
  1297. X    register struct rm *room;
  1298. X    register struct monst *mtmp;
  1299. X
  1300. X    if(u.uswallow) {
  1301. X        swallowed();
  1302. X        return;
  1303. X    }
  1304. X    cls();
  1305. X
  1306. X/* Some ridiculous code to get display of @ and monsters (almost) right */
  1307. X    if(!Invisible) {
  1308. X        levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym;
  1309. X        levl[u.udisx][u.udisy].seen = 1;
  1310. X        u.udispl = 1;
  1311. X    } else    u.udispl = 0;
  1312. X
  1313. X    seemons();    /* reset old positions */
  1314. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  1315. X        mtmp->mdispl = 0;
  1316. X    seemons();    /* force new positions to be shown */
  1317. X/* This nonsense should disappear soon --------------------------------- */
  1318. X
  1319. X#ifdef DGK
  1320. X    /* For DEC Rainbows, we must translate each character to strip
  1321. X     * out the 8th bit if necessary.
  1322. X     */
  1323. X    if (flags.DECRainbow) {
  1324. X        multipleAts = TRUE;
  1325. X        for(y = 0; y < ROWNO; y++)
  1326. X            for(x = 0; x < COLNO; x++)
  1327. X                if((room = &levl[x][y])->new) {
  1328. X                    room->new = 0;
  1329. X                    at(x,y,room->scrsym);
  1330. X                } else if(room->seen)
  1331. X                    at(x,y,room->scrsym);
  1332. X        multipleAts = FALSE;
  1333. X        if (DECgraphics)
  1334. X            DECgraphicsOFF();
  1335. X    } else {
  1336. X    /* Otherwise, line buffer the output to do the redraw in
  1337. X     * about 2/3 of the time.
  1338. X     */
  1339. X        for(y = 0; y < ROWNO; y++) {
  1340. X            char buf[COLNO+1];
  1341. X            int start, end;
  1342. X
  1343. X            memset(buf, ' ', COLNO);
  1344. X            for(x = 0, start = -1, end = -1; x < COLNO; x++)
  1345. X                if((room = &levl[x][y])->new) {
  1346. X                    room->new = 0;
  1347. X                    buf[x] = room->scrsym;
  1348. X                    if (start < 0)
  1349. X                        start = x;
  1350. X                    end = x;
  1351. X                } else if(room->seen) {
  1352. X                    buf[x] = room->scrsym;
  1353. X                    if (start < 0)
  1354. X                        start = x;
  1355. X                    end = x;
  1356. X                }
  1357. X            if (end >= 0) {
  1358. X                buf[end + 1] = '\0';
  1359. X                curs(start, y + 2);
  1360. X                fputs(buf + start, stdout);
  1361. X                curx = end + 1;
  1362. X            }
  1363. X        }
  1364. X    }
  1365. X#else
  1366. X    for(y = 0; y < ROWNO; y++)
  1367. X        for(x = 0; x < COLNO; x++)
  1368. X            if((room = &levl[x][y])->new) {
  1369. X                room->new = 0;
  1370. X                at(x,y,room->scrsym);
  1371. X            } else if(room->seen)
  1372. X                at(x,y,room->scrsym);
  1373. X#endif
  1374. X    scrlx = COLNO;
  1375. X    scrly = ROWNO;
  1376. X    scrhx = scrhy = 0;
  1377. X    flags.botlx = 1;
  1378. X    bot();
  1379. X}
  1380. X
  1381. Xdocorner(xmin,ymax) register xmin,ymax; {
  1382. X    register x,y;
  1383. X    register struct rm *room;
  1384. X    register struct monst *mtmp;
  1385. X
  1386. X    if(u.uswallow) {    /* Can be done more efficiently */
  1387. X        swallowed();
  1388. X        return;
  1389. X    }
  1390. X
  1391. X    seemons();    /* reset old positions */
  1392. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  1393. X        if(mtmp->mx >= xmin && mtmp->my < ymax)
  1394. X        mtmp->mdispl = 0;
  1395. X    seemons();    /* force new positions to be shown */
  1396. X
  1397. X#ifdef DGK
  1398. X    if (flags.DECRainbow)
  1399. X        multipleAts = TRUE;
  1400. X#endif
  1401. X    for(y = 0; y < ymax; y++) {
  1402. X        if(y > ROWNO && CD) break;
  1403. X        curs(xmin,y+2);
  1404. X        cl_end();
  1405. X        if(y < ROWNO) {
  1406. X            for(x = xmin; x < COLNO; x++) {
  1407. X            if((room = &levl[x][y])->new) {
  1408. X                room->new = 0;
  1409. X                at(x,y,room->scrsym);
  1410. X            } else
  1411. X                if(room->seen)
  1412. X                    at(x,y,room->scrsym);
  1413. X            }
  1414. X        }
  1415. X    }
  1416. X#ifdef DGK
  1417. X    if (flags.DECRainbow) {
  1418. X        multipleAts = FALSE;
  1419. X        if (DECgraphics)
  1420. X            DECgraphicsOFF();
  1421. X    }
  1422. X#endif
  1423. X    if(ymax > ROWNO) {
  1424. X        cornbot(xmin-1);
  1425. X        if(ymax > ROWNO+1 && CD) {
  1426. X            curs(1,ROWNO+3);
  1427. X            cl_eos();
  1428. X        }
  1429. X    }
  1430. X}
  1431. X
  1432. X/* Trolls now regenerate thanks to KAA */
  1433. X
  1434. Xseeobjs(){
  1435. Xregister struct obj *obj, *obj2;
  1436. X    for(obj = fobj; obj; obj = obj2) {
  1437. X        obj2 = obj->nobj;
  1438. X        if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE) {
  1439. X
  1440. X        if (obj->otyp == DEAD_TROLL && obj->age + 20 < moves) {
  1441. X            delobj(obj);
  1442. X            if (cansee(obj->ox, obj->oy)) 
  1443. X                pline("The troll rises from the dead!");
  1444. X            (void) makemon(&mons[38],obj->ox, obj->oy);
  1445. X        } else if (obj->age + 250 < moves) delobj(obj);
  1446. X        }
  1447. X    }
  1448. X
  1449. X    for(obj = invent; obj; obj = obj2) {
  1450. X        obj2 = obj->nobj;
  1451. X        if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE) {
  1452. X
  1453. X        if (obj->otyp == DEAD_TROLL && obj->age + 20 < moves) {
  1454. X            if (obj == uwep)
  1455. X            pline("The dead troll writhes out of your grasp!");
  1456. X            else
  1457. X            pline("You feel squirming in your backpack!");
  1458. X            (void)makemon(&mons[38],u.ux,u.uy);
  1459. X            useup(obj);
  1460. X        } else if (obj->age + 250 < moves) useup(obj);
  1461. X        }
  1462. X    }
  1463. X}
  1464. X
  1465. Xseemons(){
  1466. Xregister struct monst *mtmp;
  1467. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
  1468. X        if(mtmp->data->mlet == ';')
  1469. X            mtmp->minvis = (u.ustuck != mtmp &&
  1470. X                    levl[mtmp->mx][mtmp->my].typ == POOL);
  1471. X        pmon(mtmp);
  1472. X#ifndef NOWORM
  1473. X        if(mtmp->wormno) wormsee(mtmp->wormno);
  1474. X#endif
  1475. X    }
  1476. X}
  1477. X
  1478. Xpmon(mon) register struct monst *mon; {
  1479. Xregister int show = (Blind && Telepat) || canseemon(mon);
  1480. X    if(mon->mdispl){
  1481. X        if(mon->mdx != mon->mx || mon->mdy != mon->my || !show)
  1482. X            unpmon(mon);
  1483. X    }
  1484. X
  1485. X/* If you're hallucinating, the monster must be redrawn even if it has
  1486. X   already been printed.  Problem: the monster must also be redrawn right
  1487. X   after hallucination is over, so it looks normal again.  Therefore 
  1488. X   code similar to pmon is in timeout.c. */
  1489. X    if(show && (!mon->mdispl || Hallucination)) {
  1490. X        if (Hallucination) 
  1491. X        atl(mon->mx,mon->my,
  1492. X            (!mon->mimic || Protection_from_shape_changers) ?
  1493. X                rndmonsym() :
  1494. X# ifdef DGK
  1495. X                (mon->mappearance==symbol.door) ? symbol.door
  1496. X# else
  1497. X                (mon->mappearance == DOOR_SYM) ? DOOR_SYM
  1498. X# endif
  1499. X                : rndobjsym());
  1500. X        else
  1501. X
  1502. X        atl(mon->mx,mon->my,
  1503. X         (!mon->mappearance
  1504. X          || u.uprops[PROP(RIN_PROTECTION_FROM_SHAPE_CHAN)].p_flgs
  1505. X         ) ? mon->data->mlet : mon->mappearance);
  1506. X        mon->mdispl = 1;
  1507. X        mon->mdx = mon->mx;
  1508. X        mon->mdy = mon->my;
  1509. X    }
  1510. X}
  1511. X
  1512. Xunpmon(mon) register struct monst *mon; {
  1513. X    if(mon->mdispl){
  1514. X        newsym(mon->mdx, mon->mdy);
  1515. X        mon->mdispl = 0;
  1516. X    }
  1517. X}
  1518. X
  1519. Xnscr()
  1520. X{
  1521. X    register x,y;
  1522. X    register struct rm *room;
  1523. X
  1524. X    if(u.uswallow || u.ux == FAR || flags.nscrinh) return;
  1525. X    pru();
  1526. X    for(y = scrly; y <= scrhy; y++)
  1527. X        for(x = scrlx; x <= scrhx; x++)
  1528. X            if((room = &levl[x][y])->new) {
  1529. X                room->new = 0;
  1530. X                at(x,y,room->scrsym);
  1531. X            }
  1532. X    scrhx = scrhy = 0;
  1533. X    scrlx = COLNO;
  1534. X    scrly = ROWNO;
  1535. X}
  1536. X
  1537. X/* 100 suffices for bot(); no relation with COLNO */
  1538. Xchar oldbot[100], newbot[100];
  1539. Xcornbot(lth)
  1540. Xregister int lth;
  1541. X{
  1542. X    if(lth < sizeof(oldbot)) {
  1543. X        oldbot[lth] = 0;
  1544. X        flags.botl = 1;
  1545. X    }
  1546. X}
  1547. X
  1548. Xbot()
  1549. X{
  1550. Xregister char *ob = oldbot, *nb = newbot;
  1551. Xregister int i;
  1552. Xextern char *eos();
  1553. X    if(flags.botlx) *ob = 0;
  1554. X    flags.botl = flags.botlx = 0;
  1555. X    (void) sprintf(newbot,
  1556. X#ifdef GOLD_ON_BOTL
  1557. X# ifdef SPELLS
  1558. X        "Lev %-2d Gp %-5lu Hp %3d(%d) Ep %3d(%d) Ac %-2d  ",
  1559. X        dlevel, u.ugold,
  1560. X#  ifdef KAA
  1561. X        u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax : u.uhpmax,
  1562. X        u.uen, u.uenmax, u.uac);
  1563. X#  else
  1564. X        u.uhp, u.uhpmax, u.uen, u.uenmax, u.uac);
  1565. X#  endif
  1566. X# else
  1567. X        "Level %-2d  Gold %-5lu  Hp %3d(%d)  Ac %-2d  ",
  1568. X        dlevel, u.ugold,
  1569. X#  ifdef KAA
  1570. X        u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax : u.uhpmax,
  1571. X        u.uac);
  1572. X#  else
  1573. X        u.uhp, u.uhpmax, u.uac);
  1574. X#  endif
  1575. X# endif
  1576. X#else
  1577. X# ifdef SPELLS
  1578. X        "Level %-2d Hp %3d(%d) Energy %3d(%d) Ac %-2d ",
  1579. X        dlevel,
  1580. X#  ifdef KAA
  1581. X        u.mtimedone ? u.mhp : u.uhp, u.mtimedone ? u.mhmax, u.uhpmax,
  1582. X        u.uen, u.uenmax, u.uac);
  1583. X#  else
  1584. X        u.uhp, u.uhpmax, u.uen, u.uenmax, u.uac);
  1585. X#  endif
  1586. X# else
  1587. X        "Level %-2d   Hp %3d(%d)   Ac %-2d   ",
  1588. X        dlevel,
  1589. X#  ifdef KAA
  1590. X        u.mtimedone ? u.mhp : u.uhp, u.mtimedone ? u.mhmax, u.uhpmax,
  1591. X        u.uac);
  1592. X#  else
  1593. X        u.uhp, u.uhpmax, u.uac);
  1594. X#  endif
  1595. X# endif
  1596. X#endif
  1597. X#ifdef KAA
  1598. X    if (u.mtimedone)
  1599. X        (void) sprintf(eos(newbot), "HD %d", mons[u.umonnum].mlevel);
  1600. X    else
  1601. X#endif
  1602. X        if(u.ustr>18) {
  1603. X        if(u.ustr>117)
  1604. X            (void) strcat(newbot,"Str 18/**");
  1605. X        else
  1606. X            (void) sprintf(eos(newbot), "Str 18/%02d",u.ustr-18);
  1607. X        } else
  1608. X        (void) sprintf(eos(newbot), "Str %-2d   ",u.ustr);
  1609. X#ifdef EXP_ON_BOTL
  1610. X    (void) sprintf(eos(newbot), "  Exp %2d/%-5lu ", u.ulevel,u.uexp);
  1611. X#else
  1612. X    (void) sprintf(eos(newbot), "   Exp %2u  ", u.ulevel);
  1613. X#endif
  1614. X    (void) strcat(newbot, hu_stat[u.uhs]);
  1615. X    if(flags.time)
  1616. X        (void) sprintf(eos(newbot), "  %ld", moves);
  1617. X    if(strlen(newbot) >= COLNO) {
  1618. X        register char *bp0, *bp1;
  1619. X        bp0 = bp1 = newbot;
  1620. X        do {
  1621. X            if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ')
  1622. X                *bp1++ = *bp0;
  1623. X        } while(*bp0++);
  1624. X    }
  1625. X    for(i = 1; i<COLNO; i++) {
  1626. X        if(*ob != *nb){
  1627. X            curs(i,ROWNO+2);
  1628. X            (void) putchar(*nb ? *nb : ' ');
  1629. X            curx++;
  1630. X        }
  1631. X        if(*ob) ob++;
  1632. X        if(*nb) nb++;
  1633. X    }
  1634. X    (void) strcpy(oldbot, newbot);
  1635. X}
  1636. X
  1637. X#if defined(WAN_PROBING) || defined(KAA)
  1638. Xmstatusline(mtmp) register struct monst *mtmp; {
  1639. X    pline("Status of %s: ", monnam(mtmp));
  1640. X    pline("Level %-2d  Gold %-5lu  Hp %3d(%d)",
  1641. X        mtmp->data->mlevel, mtmp->mgold, mtmp->mhp, mtmp->mhpmax);
  1642. X    pline("Ac %-2d  Dam %d %s %s",
  1643. X        mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1),
  1644. X        mtmp->mcan ? ", cancelled" : "" ,mtmp->mtame ? " (tame)" : "");
  1645. X}
  1646. X
  1647. Xextern char plname[];
  1648. Xustatusline() {
  1649. X    pline("Status of %s ", plname);
  1650. X    pline("Level %d, gold %lu, hit points %d(%d), AC %d.",
  1651. X# ifdef KAA
  1652. X        u.ulevel, u.ugold, u.mtimedone ? u.mh : u.uhp,
  1653. X        u.mtimedone ? u.mhmax : u.uhpmax, u.uac);
  1654. X# else
  1655. X        u.ulevel, u.ugold, u.uhp, u.uhpmax, u.uac);
  1656. X# endif
  1657. X}
  1658. X#endif
  1659. X
  1660. Xcls(){
  1661. X    if(flags.toplin == 1)
  1662. X        more();
  1663. X    flags.toplin = 0;
  1664. X
  1665. X    clear_screen();
  1666. X
  1667. X    flags.botlx = 1;
  1668. X}
  1669. X
  1670. Xrndmonsym() {
  1671. X    register int x;
  1672. X    if((x=rn2(58)) < 26)
  1673. X        return('a'+x);
  1674. X    else if (x<52)
  1675. X        return('A'+x-26);
  1676. X    else switch(x) {
  1677. X        case 52: return(';');
  1678. X        case 53: return('&');
  1679. X        case 54: return(':');
  1680. X        case 55: return('\'');
  1681. X        case 56: return(',');
  1682. X        case 57: return('9');
  1683. X        default: impossible("Bad random monster %d",x); return('{');
  1684. X    }
  1685. X}
  1686. X
  1687. Xrndobjsym() {
  1688. X    char *rndsym=")[!?%/=*($'";
  1689. X    return *(rndsym+rn2(11));
  1690. X}
  1691. X
  1692. Xchar *hcolors[] = { "ultraviolet","infrared","hot pink", "psychedelic",
  1693. X"bluish-orange","reddish-green","dark white","light black","loud",
  1694. X"salty","sweet","sour","bitter","luminescent","striped","polka-dotted",
  1695. X"square","round","triangular","brilliant","navy blue","cerise",
  1696. X"charteruse","copper","sea green","spiral","swirly","blotchy",
  1697. X"fluorescent green","burnt orange","indigo","amber","tan",
  1698. X"sky blue-pink","lemon yellow" };
  1699. X
  1700. Xchar *
  1701. Xhcolor() {
  1702. X    return hcolors[rn2(35)];
  1703. X}
  1704. END_OF_pri.c
  1705. if test 11689 -ne `wc -c <pri.c`; then
  1706.     echo shar: \"pri.c\" unpacked with wrong size!
  1707. fi
  1708. # end of overwriting check
  1709. fi
  1710. if test -f rumors.c -a "${1}" != "-c" ; then 
  1711.   echo shar: Will not over-write existing file \"rumors.c\"
  1712. else
  1713. echo shar: Extracting \"rumors.c\" \(2892 characters\)
  1714. sed "s/^X//" >rumors.c <<'END_OF_rumors.c'
  1715. X/*    SCCS Id: @(#)rumors.c    1.3    87/07/14
  1716. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1717. X/* hack.rumors.c - version 1.0.3 */
  1718. X
  1719. X#include    <stdio.h>
  1720. X#include    "hack.h"        /* for RUMORFILE and BSD (index) */
  1721. X#ifdef DGK
  1722. X/* Rumors has been entirely rewritten to speed up the access.  This is
  1723. X * essential when working from floppies.  Using fseek() the way that's done
  1724. X * here means rumors following longer rumors are output more often than those
  1725. X * following shorter rumors.  Also, you may see the same rumor more than once
  1726. X * in a particular game (although the odds are highly against it), but
  1727. X * this also happens with real fortune cookies.  Besides, a person can
  1728. X * just read the rumor file if they desire.  -dgk
  1729. X */
  1730. Xlong rumors_size;
  1731. Xextern char *index();
  1732. Xextern long ftell();
  1733. X
  1734. Xoutrumor()
  1735. X{
  1736. X    char    line[COLNO];
  1737. X    char    *endp;
  1738. X    char    roomer[FILENAME];
  1739. X    FILE    *rumors;
  1740. X
  1741. X    if (rumors_size < 0)    /* We couldn't open RUMORFILE */
  1742. X        return;
  1743. X    if(rumors = fopen(RUMORFILE, "r")) {
  1744. X        if (!rumors_size) {    /* if this is the first outrumor() */
  1745. X            fseek(rumors, 0L, 2);
  1746. X            rumors_size = ftell(rumors);
  1747. X        }
  1748. X        fseek(rumors, rand() % rumors_size, 0);
  1749. X        fgets(line, COLNO, rumors);
  1750. X        if (!fgets(line, COLNO, rumors)) {    /* at EOF ? */
  1751. X            fseek(rumors, 0L, 0);        /* seek back to start */
  1752. X            fgets(line, COLNO, rumors);
  1753. X        }
  1754. X        if(endp = index(line, '\n')) *endp = 0;
  1755. X        pline("This cookie has a scrap of paper inside! It reads: ");
  1756. X        pline(line);
  1757. X        fclose(rumors);
  1758. X    } else {
  1759. X        pline("Can't open rumors file!");
  1760. X        rumors_size = -1;    /* don't try to open it again */
  1761. X    }
  1762. X}
  1763. X
  1764. X#else
  1765. X
  1766. X#define    CHARSZ    8            /* number of bits in a char */
  1767. Xextern long *alloc();
  1768. Xextern char *index();
  1769. Xint n_rumors = 0;
  1770. Xint n_used_rumors = -1;
  1771. Xchar *usedbits;
  1772. X
  1773. Xinit_rumors(rumf) register FILE *rumf; {
  1774. Xregister int i;
  1775. X    n_used_rumors = 0;
  1776. X    while(skipline(rumf)) n_rumors++;
  1777. X    rewind(rumf);
  1778. X    i = n_rumors/CHARSZ;
  1779. X    usedbits = (char *) alloc((unsigned)(i+1));
  1780. X    for( ; i>=0; i--) usedbits[i] = 0;
  1781. X}
  1782. X
  1783. Xskipline(rumf) register FILE *rumf; {
  1784. Xchar line[COLNO];
  1785. X    while(1) {
  1786. X        if(!fgets(line, sizeof(line), rumf)) return(0);
  1787. X        if(index(line, '\n')) return(1);
  1788. X    }
  1789. X}
  1790. X
  1791. Xoutline(rumf) register FILE *rumf; {
  1792. Xchar line[COLNO];
  1793. Xregister char *ep;
  1794. X    if(!fgets(line, sizeof(line), rumf)) return;
  1795. X    if((ep = index(line, '\n')) != 0) *ep = 0;
  1796. X    pline("This cookie has a scrap of paper inside! It reads: ");
  1797. X    pline(line);
  1798. X}
  1799. X
  1800. Xoutrumor(){
  1801. Xregister int rn,i;
  1802. Xregister FILE *rumf;
  1803. X    if(n_rumors <= n_used_rumors ||
  1804. X      (rumf = fopen(RUMORFILE, "r")) == (FILE *) 0) return;
  1805. X    if(n_used_rumors < 0) init_rumors(rumf);
  1806. X    if(!n_rumors) goto none;
  1807. X    rn = rn2(n_rumors - n_used_rumors);
  1808. X    i = 0;
  1809. X    while(rn || used(i)) {
  1810. X        (void) skipline(rumf);
  1811. X        if(!used(i)) rn--;
  1812. X        i++;
  1813. X    }
  1814. X    usedbits[i/CHARSZ] |= (1 << (i % CHARSZ));
  1815. X    n_used_rumors++;
  1816. X    outline(rumf);
  1817. Xnone:
  1818. X    (void) fclose(rumf);
  1819. X}
  1820. X
  1821. Xused(i) register int i; {
  1822. X    return(usedbits[i/CHARSZ] & (1 << (i % CHARSZ)));
  1823. X}
  1824. X
  1825. X#endif /* DGK /**/
  1826. END_OF_rumors.c
  1827. if test 2892 -ne `wc -c <rumors.c`; then
  1828.     echo shar: \"rumors.c\" unpacked with wrong size!
  1829. fi
  1830. # end of overwriting check
  1831. fi
  1832. if test -f unixmain.c -a "${1}" != "-c" ; then 
  1833.   echo shar: Will not over-write existing file \"unixmain.c\"
  1834. else
  1835. echo shar: Extracting \"unixmain.c\" \(11886 characters\)
  1836. sed "s/^X//" >unixmain.c <<'END_OF_unixmain.c'
  1837. X/*    SCCS Id: @(#)unixmain.c    1.3    87/07/14
  1838. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1839. X/* main.c - (Unix) version 1.0.3 */
  1840. X
  1841. X#include <stdio.h>
  1842. X#include <signal.h>
  1843. X#include "hack.h"
  1844. X
  1845. X#ifdef QUEST
  1846. X#define    gamename    "NetQuest"
  1847. X#else
  1848. X#define    gamename    "NetHack"
  1849. X#endif
  1850. X
  1851. Xextern char *getlogin(), *getenv();
  1852. Xextern char plname[PL_NSIZ], pl_character[PL_CSIZ];
  1853. X
  1854. Xint (*afternmv)();
  1855. Xint (*occupation)();
  1856. X
  1857. Xint done1();
  1858. Xint hangup();
  1859. X
  1860. Xint hackpid;                /* current pid */
  1861. Xint locknum;                /* max num of players */
  1862. X#ifdef DEF_PAGER
  1863. Xchar *catmore;                /* default pager */
  1864. X#endif
  1865. Xchar SAVEF[PL_NSIZ + 11] = "save/";    /* save/99999player */
  1866. Xchar *hname;        /* name of the game (argv[0] of call) */
  1867. Xchar obuf[BUFSIZ];    /* BUFSIZ is defined in stdio.h */
  1868. X
  1869. Xextern char *nomovemsg;
  1870. Xextern long wailmsg;
  1871. X
  1872. Xmain(argc,argv)
  1873. Xint argc;
  1874. Xchar *argv[];
  1875. X{
  1876. X    register int fd;
  1877. X#ifdef CHDIR
  1878. X    register char *dir;
  1879. X#endif
  1880. X
  1881. X    hname = argv[0];
  1882. X    hackpid = getpid();
  1883. X
  1884. X#ifdef CHDIR            /* otherwise no chdir() */
  1885. X    /*
  1886. X     * See if we must change directory to the playground.
  1887. X     * (Perhaps hack runs suid and playground is inaccessible
  1888. X     *  for the player.)
  1889. X     * The environment variable HACKDIR is overridden by a
  1890. X     *  -d command line option (must be the first option given)
  1891. X     */
  1892. X
  1893. X    dir = getenv("HACKDIR");
  1894. X    if(argc > 1 && !strncmp(argv[1], "-d", 2)) {
  1895. X        argc--;
  1896. X        argv++;
  1897. X        dir = argv[0]+2;
  1898. X        if(*dir == '=' || *dir == ':') dir++;
  1899. X        if(!*dir && argc > 1) {
  1900. X            argc--;
  1901. X            argv++;
  1902. X            dir = argv[0];
  1903. X        }
  1904. X        if(!*dir)
  1905. X            error("Flag -d must be followed by a directory name.");
  1906. X    }
  1907. X#endif /* CHDIR /**/
  1908. X#ifdef DGKMOD
  1909. X    initoptions();
  1910. X#endif
  1911. X    whoami();
  1912. X    /*
  1913. X     * Now we know the directory containing 'record' and
  1914. X     * may do a prscore().
  1915. X     */
  1916. X    if(argc > 1 && !strncmp(argv[1], "-s", 2)) {
  1917. X#ifdef CHDIR
  1918. X        chdirx(dir,0);
  1919. X#endif
  1920. X        prscore(argc, argv);
  1921. X        exit(0);
  1922. X    }
  1923. X
  1924. X    /*
  1925. X     * It seems he really wants to play.
  1926. X     * Remember tty modes, to be restored on exit.
  1927. X     */
  1928. X    gettty();
  1929. X    setbuf(stdout,obuf);
  1930. X    setrandom();
  1931. X    startup();
  1932. X    init_corpses();    /* initialize optional corpse names */
  1933. X    cls();
  1934. X    u.uhp = 1;    /* prevent RIP on early quits */
  1935. X    u.ux = FAR;    /* prevent nscr() */
  1936. X    (void) signal(SIGHUP, hangup);
  1937. X
  1938. X    /*
  1939. X     * Find the creation date of this game,
  1940. X     * so as to avoid restoring outdated savefiles.
  1941. X     */
  1942. X    gethdate(hname);
  1943. X
  1944. X    /*
  1945. X     * We cannot do chdir earlier, otherwise gethdate will fail.
  1946. X     */
  1947. X#ifdef CHDIR
  1948. X    chdirx(dir,1);
  1949. X#endif
  1950. X
  1951. X    /*
  1952. X     * Process options.
  1953. X     */
  1954. X    while(argc > 1 && argv[1][0] == '-'){
  1955. X        argv++;
  1956. X        argc--;
  1957. X        switch(argv[0][1]){
  1958. X#ifdef WIZARD
  1959. X        case 'D':
  1960. X            if(!strcmp(getlogin(), WIZARD))
  1961. X                wizard = TRUE;
  1962. X            else
  1963. X                printf("Sorry.\n");
  1964. X            break;
  1965. X#endif
  1966. X#ifdef NEWS
  1967. X        case 'n':
  1968. X            flags.nonews = TRUE;
  1969. X            break;
  1970. X#endif
  1971. X        case 'u':
  1972. X            if(argv[0][2])
  1973. X              (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
  1974. X            else if(argc > 1) {
  1975. X              argc--;
  1976. X              argv++;
  1977. X              (void) strncpy(plname, argv[0], sizeof(plname)-1);
  1978. X            } else
  1979. X                printf("Player name expected after -u\n");
  1980. X            break;
  1981. X        default:
  1982. X            /* allow -T for Tourist, etc. */
  1983. X            (void) strncpy(pl_character, argv[0]+1,
  1984. X                sizeof(pl_character)-1);
  1985. X
  1986. X            /* printf("Unknown option: %s\n", *argv); */
  1987. X        }
  1988. X    }
  1989. X
  1990. X    if(argc > 1)
  1991. X        locknum = atoi(argv[1]);
  1992. X#ifdef MAX_NR_OF_PLAYERS
  1993. X    if(!locknum || locknum > MAX_NR_OF_PLAYERS)
  1994. X        locknum = MAX_NR_OF_PLAYERS;
  1995. X#endif
  1996. X#ifdef DEF_PAGER
  1997. X    if(!(catmore = getenv("HACKPAGER")) && !(catmore = getenv("PAGER")))
  1998. X        catmore = DEF_PAGER;
  1999. X#endif
  2000. X#ifdef MAIL
  2001. X    getmailstatus();
  2002. X#endif
  2003. X#ifdef WIZARD
  2004. X    if(wizard) (void) strcpy(plname, "wizard"); else
  2005. X#endif
  2006. X    if(!*plname || !strncmp(plname, "player", 4)
  2007. X            || !strncmp(plname, "games", 4))
  2008. X        askname();
  2009. X    plnamesuffix();        /* strip suffix from name; calls askname() */
  2010. X                /* again if suffix was whole name */
  2011. X                /* accepts any suffix */
  2012. X#ifdef WIZARD
  2013. X    if(!wizard) {
  2014. X#endif
  2015. X        /*
  2016. X         * check for multiple games under the same name
  2017. X         * (if !locknum) or check max nr of players (otherwise)
  2018. X         */
  2019. X        (void) signal(SIGQUIT,SIG_IGN);
  2020. X        (void) signal(SIGINT,SIG_IGN);
  2021. X        if(!locknum)
  2022. X            (void) strcpy(lock,plname);
  2023. X        getlock();    /* sets lock if locknum != 0 */
  2024. X#ifdef WIZARD
  2025. X    } else {
  2026. X        register char *sfoo;
  2027. X        extern char genocided[], fut_geno[];
  2028. X        (void) strcpy(lock,plname);
  2029. X        if(sfoo = getenv("MAGIC"))
  2030. X            while(*sfoo) {
  2031. X                switch(*sfoo++) {
  2032. X                case 'n': (void) srand(*sfoo++);
  2033. X                    break;
  2034. X                }
  2035. X            }
  2036. X        if(sfoo = getenv("GENOCIDED")){
  2037. X            if(*sfoo == '!'){
  2038. X                extern struct permonst mons[CMNUM+2];
  2039. X                register struct permonst *pm = mons;
  2040. X                register char *gp = genocided;
  2041. X
  2042. X                while(pm < mons+CMNUM+2){
  2043. X                    if(!index(sfoo, pm->mlet))
  2044. X                        *gp++ = pm->mlet;
  2045. X                    pm++;
  2046. X                }
  2047. X                *gp = 0;
  2048. X            } else
  2049. X                (void) strcpy(genocided, sfoo);
  2050. X            (void) strcpy(fut_geno, genocided);
  2051. X        }
  2052. X    }
  2053. X#endif /* WIZARD /**/
  2054. X    setftty();
  2055. X    (void) sprintf(SAVEF, "save/%d%s", getuid(), plname);
  2056. X    regularize(SAVEF+5);        /* avoid . or / in name */
  2057. X    if((fd = open(SAVEF,0)) >= 0 &&
  2058. X       (uptodate(fd) || unlink(SAVEF) == 666)) {
  2059. X        (void) signal(SIGINT,done1);
  2060. X        pline("Restoring old save file...");
  2061. X        (void) fflush(stdout);
  2062. X        if(!dorecover(fd))
  2063. X            goto not_recovered;
  2064. X        pline("Hello %s, welcome to %s!", plname, gamename);
  2065. X        flags.move = 0;
  2066. X    } else {
  2067. Xnot_recovered:
  2068. X        newgame();
  2069. X        /* give welcome message before pickup messages */
  2070. X        pline("Hello %s, welcome to %s!", plname, gamename);
  2071. X
  2072. X        pickup(1);
  2073. X        if(!Blind) read_engr_at(u.ux,u.uy);
  2074. X        flags.move = 1;
  2075. X    }
  2076. X
  2077. X    flags.moonphase = phase_of_the_moon();
  2078. X    if(flags.moonphase == FULL_MOON) {
  2079. X        pline("You are lucky! Full moon tonight.");
  2080. X        if(!u.uluck) u.uluck++;
  2081. X    } else if(flags.moonphase == NEW_MOON) {
  2082. X        pline("Be careful! New moon tonight.");
  2083. X    }
  2084. X
  2085. X    initrack();
  2086. X
  2087. X    for(;;) {
  2088. X        if(flags.move) {    /* actual time passed */
  2089. X
  2090. X            settrack();
  2091. X
  2092. X            if(moves%2 == 0 ||
  2093. X              (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) {
  2094. X                extern struct monst *makemon();
  2095. X                movemon();
  2096. X                if(!rn2(70))
  2097. X                    (void) makemon((struct permonst *)0, 0, 0);
  2098. X            }
  2099. X            if(Glib) glibr();
  2100. X            timeout();
  2101. X            ++moves;
  2102. X#ifdef PRAYERS
  2103. X            if (u.ublesscnt)  u.ublesscnt--;
  2104. X#endif
  2105. X            if(flags.time) flags.botl = 1;
  2106. X#ifdef KAA
  2107. X            if(u.mtimedone)
  2108. X                if(u.mh < 1) rehumanize();
  2109. X            else
  2110. X#endif
  2111. X                if(u.uhp < 1) {
  2112. X                pline("You die...");
  2113. X                done("died");
  2114. X                }
  2115. X            if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50){
  2116. X                wailmsg = moves;
  2117. X#ifdef KAA
  2118. X                if(index("WEV", pl_character[0])) {
  2119. X                if (u.uhp == 1)
  2120. X                pline("%s is about to die.", pl_character);
  2121. X                else
  2122. X                pline("%s, your life force is running out.",
  2123. X                    pl_character);
  2124. X                } else {
  2125. X#endif
  2126. X                if(u.uhp == 1)
  2127. X                pline("You hear the wailing of the Banshee...");
  2128. X                else
  2129. X                pline("You hear the howling of the CwnAnnwn...");
  2130. X#ifdef KAA
  2131. X                }
  2132. X#endif
  2133. X            }
  2134. X#ifdef KAA
  2135. X            if (u.mtimedone) {
  2136. X                if (u.mh < u.mhmax) {
  2137. X                if (Regeneration || !(moves%20)) {
  2138. X                    flags.botl = 1;
  2139. X                    u.mh++;
  2140. X                }
  2141. X                }
  2142. X            }
  2143. X#endif
  2144. X            if(u.uhp < u.uhpmax) {
  2145. X                if(u.ulevel > 9) {
  2146. X                    if(HRegeneration || !(moves%3)) {
  2147. X                        flags.botl = 1;
  2148. X                        u.uhp += rnd((int) u.ulevel-9);
  2149. X                        if(u.uhp > u.uhpmax)
  2150. X                        u.uhp = u.uhpmax;
  2151. X                    }
  2152. X                } else if(HRegeneration ||
  2153. X                    (!(moves%(22-u.ulevel*2)))) {
  2154. X                    flags.botl = 1;
  2155. X                    u.uhp++;
  2156. X                }
  2157. X            }
  2158. X#ifdef SPELLS
  2159. X            if ((u.uen<u.uenmax) && (!(moves%(21-u.ulevel/2)))) {
  2160. X                u.uen += rn2(u.ulevel/4 + 1) + 1;
  2161. X                if (u.uen > u.uenmax)  u.uen = u.uenmax;
  2162. X                flags.botl = 1;
  2163. X            }
  2164. X#endif
  2165. X            if(Teleportation && !rn2(85)) tele();
  2166. X            if(Searching && multi >= 0) (void) dosearch();
  2167. X            gethungry();
  2168. X            invault();
  2169. X            amulet();
  2170. X#ifdef HARD
  2171. X            if (u.udemigod) {
  2172. X
  2173. X                u.udg_cnt--;
  2174. X                if(u.udg_cnt <= 0) {
  2175. X
  2176. X                    intervene();
  2177. X                    u.udg_cnt = rn1(200, 50);
  2178. X                }
  2179. X            }
  2180. X#endif
  2181. X        }
  2182. X        if(multi < 0) {
  2183. X            if(!++multi){
  2184. X                pline(nomovemsg ? nomovemsg :
  2185. X                    "You can move again.");
  2186. X                nomovemsg = 0;
  2187. X                if(afternmv) (*afternmv)();
  2188. X                afternmv = 0;
  2189. X            }
  2190. X        }
  2191. X
  2192. X        find_ac();
  2193. X#ifndef QUEST
  2194. X        if(!flags.mv || Blind)
  2195. X#endif
  2196. X        {
  2197. X            seeobjs();
  2198. X            seemons();
  2199. X            nscr();
  2200. X        }
  2201. X#ifdef DGK
  2202. X        if(flags.time) flags.botl = 1;
  2203. X#endif
  2204. X        if(flags.botl || flags.botlx) bot();
  2205. X
  2206. X        flags.move = 1;
  2207. X
  2208. X        if(multi >= 0 && occupation) {
  2209. X
  2210. X            if (monster_nearby())
  2211. X                stop_occupation();
  2212. X            else if ((*occupation)() == 0)
  2213. X                occupation = 0;
  2214. X            continue;
  2215. X        }
  2216. X
  2217. X        if(multi > 0) {
  2218. X#ifdef QUEST
  2219. X            if(flags.run >= 4) finddir();
  2220. X#endif
  2221. X            lookaround();
  2222. X            if(!multi) {    /* lookaround may clear multi */
  2223. X                flags.move = 0;
  2224. X                continue;
  2225. X            }
  2226. X            if(flags.mv) {
  2227. X                if(multi < COLNO && !--multi)
  2228. X                    flags.mv = flags.run = 0;
  2229. X                domove();
  2230. X            } else {
  2231. X                --multi;
  2232. X                rhack(save_cm);
  2233. X            }
  2234. X        } else if(multi == 0) {
  2235. X#ifdef MAIL
  2236. X            ckmailstatus();
  2237. X#endif
  2238. X            rhack((char *) 0);
  2239. X        }
  2240. X        if(multi && multi%7 == 0)
  2241. X            (void) fflush(stdout);
  2242. X    }
  2243. X}
  2244. X
  2245. Xglo(foo)
  2246. Xregister foo;
  2247. X{
  2248. X    /* construct the string  xlock.n  */
  2249. X    register char *tf;
  2250. X
  2251. X    tf = lock;
  2252. X    while(*tf && *tf != '.') tf++;
  2253. X    (void) sprintf(tf, ".%d", foo);
  2254. X}
  2255. X
  2256. X/*
  2257. X * plname is filled either by an option (-u Player  or  -uPlayer) or
  2258. X * explicitly (-w implies wizard) or by askname.
  2259. X * It may still contain a suffix denoting pl_character.
  2260. X */
  2261. Xaskname(){
  2262. Xregister int c,ct;
  2263. X    printf("\nWho are you? ");
  2264. X    (void) fflush(stdout);
  2265. X    ct = 0;
  2266. X    while((c = getchar()) != '\n'){
  2267. X        if(c == EOF) error("End of input\n");
  2268. X        /* some people get confused when their erase char is not ^H */
  2269. X        if(c == '\010') {
  2270. X            if(ct) ct--;
  2271. X            continue;
  2272. X        }
  2273. X        if(c != '-')
  2274. X        if(c < 'A' || (c > 'Z' && c < 'a') || c > 'z') c = '_';
  2275. X        if(ct < sizeof(plname)-1) plname[ct++] = c;
  2276. X    }
  2277. X    plname[ct] = 0;
  2278. X    if(ct == 0) askname();
  2279. X}
  2280. X
  2281. X/*VARARGS1*/
  2282. Ximpossible(s,x1,x2)
  2283. Xregister char *s;
  2284. X{
  2285. X    pline(s,x1,x2);
  2286. X    pline("Program in disorder - perhaps you'd better Quit.");
  2287. X}
  2288. X
  2289. X#ifdef CHDIR
  2290. Xstatic
  2291. Xchdirx(dir, wr)
  2292. Xchar *dir;
  2293. Xboolean wr;
  2294. X{
  2295. X
  2296. X# ifdef SECURE
  2297. X    if(dir                    /* User specified directory? */
  2298. X#  ifdef HACKDIR
  2299. X           && strcmp(dir, HACKDIR)        /* and not the default? */
  2300. X#  endif
  2301. X        ) {
  2302. X        (void) setuid(getuid());        /* Ron Wessels */
  2303. X        (void) setgid(getgid());
  2304. X    }
  2305. X# endif
  2306. X
  2307. X# ifdef HACKDIR
  2308. X    if(dir == NULL)
  2309. X        dir = HACKDIR;
  2310. X# endif
  2311. X
  2312. X    if(dir && chdir(dir) < 0) {
  2313. X        perror(dir);
  2314. X        error("Cannot chdir to %s.", dir);
  2315. X    }
  2316. X
  2317. X    /* warn the player if he cannot write the record file */
  2318. X    /* perhaps we should also test whether . is writable */
  2319. X    /* unfortunately the access systemcall is worthless */
  2320. X    if(wr) {
  2321. X        register fd;
  2322. X
  2323. X        if(dir == NULL)
  2324. X        dir = ".";
  2325. X        if((fd = open(RECORD, 2)) < 0) {
  2326. X        printf("Warning: cannot write %s/%s", dir, RECORD);
  2327. X        getret();
  2328. X        } else
  2329. X        (void) close(fd);
  2330. X    }
  2331. X}
  2332. X#endif /* CHDIR /**/
  2333. X
  2334. Xstop_occupation()
  2335. X{
  2336. X    if(occupation) {
  2337. X        pline("You stop %s.", occtxt);
  2338. X        occupation = 0;
  2339. X#ifdef REDO
  2340. X        multi = 0;
  2341. X        pushch(0);        
  2342. X#endif
  2343. X    }
  2344. X}
  2345. X
  2346. Xwhoami() {
  2347. X    /*
  2348. X     * Who am i? Algorithm: 1. Use name as specified in HACKOPTIONS
  2349. X     *            2. Use $USER or $LOGNAME    (if 1. fails)
  2350. X     *            3. Use getlogin()        (if 2. fails)
  2351. X     * The resulting name is overridden by command line options.
  2352. X     * If everything fails, or if the resulting name is some generic
  2353. X     * account like "games", "play", "player", "hack" then eventually
  2354. X     * we'll ask him.
  2355. X     * Note that we trust him here; it is possible to play under
  2356. X     * somebody else's name.
  2357. X     */
  2358. X    register char *s;
  2359. X
  2360. X#ifndef DGKMOD
  2361. X    initoptions();
  2362. X#endif
  2363. X    if(!*plname && (s = getenv("USER")))
  2364. X        (void) strncpy(plname, s, sizeof(plname)-1);
  2365. X    if(!*plname && (s = getenv("LOGNAME")))
  2366. X        (void) strncpy(plname, s, sizeof(plname)-1);
  2367. X    if(!*plname && (s = getlogin()))
  2368. X        (void) strncpy(plname, s, sizeof(plname)-1);
  2369. X}
  2370. X
  2371. Xnewgame() {
  2372. X    fobj = fcobj = invent = 0;
  2373. X    fmon = fallen_down = 0;
  2374. X    ftrap = 0;
  2375. X    fgold = 0;
  2376. X    flags.ident = 1;
  2377. X    init_objects();
  2378. X    u_init();
  2379. X
  2380. X    (void) signal(SIGINT,done1);
  2381. X    mklev();
  2382. X    u.ux = xupstair;
  2383. X    u.uy = yupstair;
  2384. X    (void) inshop();
  2385. X    setsee();
  2386. X    flags.botlx = 1;
  2387. X    {
  2388. X        register struct monst *mtmp;
  2389. X
  2390. X        /* Move the monster from under you or else
  2391. X         * makedog() will fail when it calls makemon().
  2392. X         *             - ucsfcgl!kneller
  2393. X         */
  2394. X        if (mtmp = m_at(u.ux, u.uy))  mnexto(mtmp);
  2395. X    }
  2396. X    (void) makedog();
  2397. X    seemons();
  2398. X#ifdef NEWS
  2399. X    if(flags.nonews || !readnews())
  2400. X        /* after reading news we did docrt() already */
  2401. X#endif
  2402. X        docrt();
  2403. X    return(0);
  2404. X}
  2405. END_OF_unixmain.c
  2406. if test 11886 -ne `wc -c <unixmain.c`; then
  2407.     echo shar: \"unixmain.c\" unpacked with wrong size!
  2408. fi
  2409. # end of overwriting check
  2410. fi
  2411. echo shar: End of archive 9 \(of 16\).
  2412. cp /dev/null ark9isdone
  2413. MISSING=""
  2414. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
  2415.     if test ! -f ark${I}isdone ; then
  2416.     MISSING="${MISSING} ${I}"
  2417.     fi
  2418. done
  2419. if test "${MISSING}" = "" ; then
  2420.     echo You have unpacked all 16 archives.
  2421.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2422. else
  2423.     echo You still need to unpack the following archives:
  2424.     echo "        " ${MISSING}
  2425. fi
  2426. ##  End of shell archive.
  2427. exit 0
  2428.